<template>
  <!-- isZoomin &&  -->
  <div id="zommMask" ref="container" @pointerdown.stop="mouseDown"
       :style="{cursor: !isZoomin && zoomImage.image?'default':'crosshair','background-color': !zoomImage.image?'transparent':'rgba(0, 0, 0, 0.4)'}">
    <slide-element
      v-if="isZoomin && !zoomImage.image"
      ref="slideElement"
      :ContainerSize="containerSize"
      :ElementStyle="{position:'absolute',cursor:'move',border:'2px solid red'}"
      :Location="location"
      :Activated="true"
      :KeyboardMove="false"
      :isChangeSize="false"
      @LocSizeChanged="LocSizeChanged"/>
    <div class="container"
         style="width: 100%;height: 100%;position: absolute;overflow: hidden"
         v-if="!isZoomin && zoomImage.image">
      <!--<img :src="zoomImage.image"-->
      <!--:style="imageStyle"-->
      <!--style="float: left;position: absolute;object-fit: fill;"-->
      <!--/>-->
      <canvas ref="canvas"
              :width="imageSize.width"
              :height="imageSize.height"
              :style="canvasStyle"
              :class="{brush:zoomImage.isDraw}"
              @mousedown.stop="zoomImage.isDraw?drawTrajectory():SetImageDisplayArea()"
              @mousewheel="imageShrink"/>
    </div>
  </div>
</template>
<script>
  import SlideElement from './SlideElement'
  import action from '../../common/typeActions'
  import {mapState, mapActions} from 'vuex'

  let remote = ''

  export default {
    name: 'SlideZoomViewer',
    components: {
      'slide-element': SlideElement
    },
    data: function () {
      return {
        image: null,
        isZoomin: false,
        zoomScale: 0,
        containerSize: {width: 0, height: 0},
        location: {},
        canvasContext: null
      }
    },
    props: {
      disable: {type: Boolean, default: false}
    },
    computed: {
      ...mapState({
        zoomImage: state => state.slideEditor.zoomImage,
        defaultBrush: state => state.slideEditor.customized.DefaultBrush
      }),
      imageSize: {
        get () {
          return {
            width: this.zoomImage.width * this.containerSize.width,
            height: this.zoomImage.height * this.containerSize.height
          }
        }
      },
      imageStyle: {
        get () {
          return {
            width: `${this.zoomImage.width * this.containerSize.width}px`,
            height: `${this.zoomImage.height * this.containerSize.height}px`,
            left: `${this.zoomImage.left * this.containerSize.width}px`,
            top: `${this.zoomImage.top * this.containerSize.height}px`
          }
        }
      },
      canvasStyle: {
        get () {
          return {
            left: `${this.zoomImage.left * this.containerSize.width}px`,
            top: `${this.zoomImage.top * this.containerSize.height}px`
          }
        }
      }
    },
    mounted: function () {
      this.$nextTick(() => {
        let container = this.$refs.container
        this.containerSize = {
          width: container.offsetWidth,
          height: container.offsetHeight
        }
      })
    },
    watch: {
      'zoomImage.sign': function (n, o) {
        this.paintTrajectory(n)
      },
      'zoomImage.image': function (n, o) {
        this.image = new Image()
        this.image.src = n
        this.image.onload = () => {
          this.paintTrajectory()
        }
      }
    },
    methods: {
      ...mapActions({
        SetEditorZoomAttr: action.SLIDEEDITOR.SetEditorZoomAttr,
        AddEditorZoomSign: action.SLIDEEDITOR.AddEditorZoomSign,
        AddEditorZoomSignLocation: action.SLIDEEDITOR.AddEditorZoomSignLocation
      }),
      imageShrink: function () {
        if ((event.deltaY > 0 && !this.zoomScale) || (event.deltaY < 0 && this.zoomScale >= 2)) return
        let oldScale = this.zoomScale
        this.zoomScale = parseFloat((this.zoomScale + (event.deltaY > 0 ? -0.1 : 0.1)).toFixed(1))

        let zoomScale = this.zoomScale - oldScale

        this.SetEditorZoomAttr([
          {
            attrName: 'width',
            attrValue: this.zoomImage.width + zoomScale
          },
          {
            attrName: 'height',
            attrValue: this.zoomImage.height + zoomScale
          },
          {
            attrName: 'left',
            attrValue: (1 - this.zoomImage.width - zoomScale) / 2
          },
          {
            attrName: 'top',
            attrValue: (1 - this.zoomImage.height - zoomScale) / 2
          }
        ])
        this.paintTrajectory(this.zoomImage.sign)
      },
      SetImageDisplayArea: function () {
        let self = this
        if (event.buttons !== 1) return

        let zoomSize = {
          width: this.zoomScale * this.containerSize.width,
          height: this.zoomScale * this.containerSize.height
        }
        let loc = {x: event.clientX, y: event.clientY}
        event.target.onmousemove = () => {
          if (event.buttons !== 1) {
            event.target.onmouseup = event.target.onmousemove = null
            return
          }

          let imageLoc = {
            left: this.zoomImage.left * this.containerSize.width,
            top: this.zoomImage.top * this.containerSize.height
          }

          // 当图片宽度超过容器大小，允许移动图片
          if (self.zoomImage.width > 1) {
            let moveWidth = event.clientX - loc.x
            // 向右移动
            if (moveWidth > 0) {
              imageLoc.left = imageLoc.left + moveWidth >= 0 ? 0 : imageLoc.left + moveWidth
            } else if (moveWidth < 0) {
              imageLoc.left = Math.abs(imageLoc.left) >= zoomSize.width ? -zoomSize.width : imageLoc.left + moveWidth
            }
          }
          // 当图片高度超过容器大小，允许移动图片
          if (self.zoomImage.height > 1) {
            let moveHeight = event.clientY - loc.y
            // 向下移动
            if (moveHeight > 0) {
              imageLoc.top = imageLoc.top + moveHeight >= 0 ? 0 : imageLoc.top + moveHeight
            } else if (moveHeight < 0) {
              imageLoc.top = Math.abs(imageLoc.top) >= zoomSize.height ? -zoomSize.height : imageLoc.top + moveHeight
            }
          }

          self.SetEditorZoomAttr([
            {attrName: 'left', attrValue: imageLoc.left / self.containerSize.width},
            {attrName: 'top', attrValue: imageLoc.top / self.containerSize.height}])
          loc = {x: event.clientX, y: event.clientY}
        }
        event.target.onpointerup = () => {
          event.target.onpointerup = event.target.onpointermove = null
        }
      },
      mouseDown: function () {
        if (this.disable) return
        let self = this
        let container = self.$refs.container
        if (!container || self.isZoomin || self.zoomImage.image) return

        self.isZoomin = true
        self.location = {
          left: event.offsetX / self.containerSize.width,
          top: event.offsetY / self.containerSize.height
        }
        self.$nextTick(function () {
          let slideElement = self.$refs.slideElement
          if (slideElement) slideElement.setDragDirection('setLowerRightCorner')
        })
      },
      LocSizeChanged (obj) {
        let self = this

        let slideElement = self.$refs.slideElement
        if (!slideElement) return

        let size = {
          x: parseInt(slideElement.$el.getBoundingClientRect().left + 3),
          y: parseInt(slideElement.$el.getBoundingClientRect().top + 3),
          width: parseInt(obj.width - 3),
          height: parseInt(obj.height - 3)
        }
        self.isZoomin = false

        remote.getCurrentWindow().capturePage(size, img => {
          if (obj.width > obj.height) {
            let ratio = obj.height / obj.width
            obj.width = self.containerSize.width
            obj.height =
              obj.width * ratio > self.containerSize.height
                ? self.containerSize.height
                : obj.width * ratio
          } else {
            let ratio = obj.width / obj.height
            obj.height = self.containerSize.height
            obj.width =
              obj.height * ratio > self.containerSize.width
                ? self.containerSize.width
                : obj.height * ratio
          }
          self.SetEditorZoomAttr([
            {
              attrName: 'image',
              attrValue: img.toDataURL()
            },
            {
              attrName: 'width',
              attrValue: obj.width / self.containerSize.width
            },
            {
              attrName: 'height',
              attrValue: obj.height / self.containerSize.height
            },
            {
              attrName: 'left',
              attrValue: (self.containerSize.width - obj.width) / 2 / self.containerSize.width
            },
            {
              attrName: 'top',
              attrValue: (self.containerSize.height - obj.height) / 2 / self.containerSize.height
            }
          ])
        })
      },
      // 获取标注轨迹
      drawTrajectory: function () {
        let self = this
        if (this.disable || !this.zoomImage.isDraw) return
        let canvas = this.$refs.canvas
        if (!canvas) return

        self.AddEditorZoomSign()
        canvas.onmousemove = function () {
          self.AddEditorZoomSignLocation({
            x: event.offsetX / canvas.offsetWidth,
            y: event.offsetY / canvas.offsetHeight
          })
        }
        canvas.onmouseup = () => {
          canvas.onmouseup = canvas.onmousemove = null
        }
        canvas.onmouseout = () => {
          canvas.onmouseout = canvas.onmousemove = null
        }
      },
      // 绘制标注轨迹
      paintTrajectory: function (trajectory = []) {
        this.$nextTick(() => {
          let canvas = this.$refs.canvas
          if (!this.canvasContext) {
            this.canvasContext = canvas.getContext('2d')
          } else {
            this.canvasContext.clearRect(
              0,
              0,
              this.imageSize.width,
              this.imageSize.height
            )
          }

          this.canvasContext.drawImage(this.image, 0, 0, this.imageSize.width, this.imageSize.height)

          this.canvasContext.strokeStyle = this.defaultBrush.color
          this.canvasContext.lineWidth = this.defaultBrush.width
          trajectory.forEach(item => {
            this.canvasContext.beginPath()
            item.forEach(location => {
              let loc = {
                x: location.x * canvas.offsetWidth,
                y: location.y * canvas.offsetHeight
              }

              this.canvasContext.lineTo(loc.x, loc.y)
              this.canvasContext.moveTo(loc.x, loc.y)
            })

            this.canvasContext.closePath()
            this.canvasContext.stroke()
          })
        })
      }
    }
  }
</script>
<style scoped>
  #zommMask {
    width: 100%;
    height: 100%;
    z-index: 600;
    position: absolute;
    top: 0;
    overflow: auto;
  }

  #zommMask .container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    max-width: 100%;
    max-height: 100%;
  }

  #zommMask img {
    width: 100%;
    height: 100%;
  }

  #zommMask canvas {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1000;
  }

  .brush {
    cursor: url("~@/assets/img/SlideEditor/brush.png"), auto;
  }
</style>
